/**
 * Create by CaoWenjian
 *
 * @copyRight: 2018
 **/
package com.bjboot.caocao.system.service.impl;

import com.bjboot.caocao.common.exception.BJException;
import com.bjboot.caocao.common.utils.BuildTreeUtil;
import com.bjboot.caocao.common.utils.FileUtil;
import com.bjboot.caocao.common.utils.ImageUtils;
import com.bjboot.caocao.common.utils.MD5Utils;
import com.bjboot.caocao.system.config.BJBootSysConfigParam;
import com.bjboot.caocao.system.dao.DeptMapper;
import com.bjboot.caocao.system.dao.FileMapper;
import com.bjboot.caocao.system.dao.UserDao;
import com.bjboot.caocao.system.dao.UserRoleMapper;
import com.bjboot.caocao.system.domain.*;
import com.bjboot.caocao.system.pojo.UserPwdPojo;
import com.bjboot.caocao.system.service.UserService;
import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.*;

/**
 *@Description 用户处理实现类
 *@Author 操文健
 *@Date 2018-09-07 上午11:39
 *@Version 1.0
 **/
@Service
public class UserServiceImpl implements UserService {

    private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserDao userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private BJBootSysConfigParam bjBootSysConfigParam;

    @Override
    public UserDO getUserById(Long userId) {
        return userMapper.get(userId);
    }

    @Override
    public boolean updatePersonal(UserDO user) {
        // 根据返回的结果判断是否更新成功
        return userMapper.update(user) > 0 ? true : false;
    }

    @Override
    public int resetPwd(UserPwdPojo userPojo, UserDO user) throws BJException {
        if (Objects.equals(userPojo.getUserDO().getUserId(), user.getUserId())) {
            if (Objects.equals(MD5Utils.encrypt(user.getUsername(), userPojo.getPwdOld()), user.getPassword())) {
                user.setPassword(MD5Utils.encrypt(user.getUsername(), userPojo.getPwdNew()));
                return userMapper.update(user);
            } else {
                throw new BJException("输入的旧密码有误！");
            }
        } else {
            throw new BJException("你修改的不是你登录的账号！");
        }
    }

    @Override
    public int adminResetPwd(UserPwdPojo userVO) throws BJException {
        UserDO userDO = get(userVO.getUserDO().getUserId());
        if ("admin".equals(userDO.getUsername())) {
            throw new BJException("超级管理员的账号不允许直接重置！");
        }
        userDO.setPassword(MD5Utils.encrypt(userDO.getUsername(), userVO.getPwdNew()));
        return userMapper.update(userDO);
    }

    @Override
    public UserDO get(Long id) {
        List<Long> roleIds = userRoleMapper.listRoleId(id);
        UserDO user = userMapper.get(id);
        user.setDeptName(deptMapper.selectByPrimaryKey(user.getDeptId()).getName());
        user.setRoleIds(roleIds);
        return user;
    }

    @Override
    public Map<String, Object> updatePersonalImg(MultipartFile file, String avatar_data, Long userId) throws Exception {
        String fileName = file.getOriginalFilename();
        fileName = FileUtil.renameToUUID(fileName);
        // 创建文件domain对象
        FileDO sysFile = new FileDO(FileUtil.fileType(fileName), "/files/" + fileName, new Date());
        //获取图片后缀
        String prefix = fileName.substring((fileName.lastIndexOf(".") + 1));
        String[] str = avatar_data.split(",");
        //获取截取的x坐标
        int x = (int) Math.floor(Double.parseDouble(str[0].split(":")[1]));
        //获取截取的y坐标
        int y = (int) Math.floor(Double.parseDouble(str[1].split(":")[1]));
        //获取截取的高度
        int h = (int) Math.floor(Double.parseDouble(str[2].split(":")[1]));
        //获取截取的宽度
        int w = (int) Math.floor(Double.parseDouble(str[3].split(":")[1]));
        //获取旋转的角度
        int r = Integer.parseInt(str[4].split(":")[1].replaceAll("}", ""));
        try {
            BufferedImage cutImage = ImageUtils.cutImage(file, x, y, w, h, prefix);
            BufferedImage rotateImage = ImageUtils.rotateImage(cutImage, r);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            boolean flag = ImageIO.write(rotateImage, prefix, out);
            //转换后存入数据库
            byte[] b = out.toByteArray();
            FileUtil.uploadFile(b, bjBootSysConfigParam.getUploadPath(), fileName);
            logger.info("配置文件上传的图片路径为：" + bjBootSysConfigParam.getUploadPath());
        } catch (Exception e) {
            logger.info("图片裁剪出现异常", e);
            throw new Exception("图片裁剪错误！！");
        }
        Map<String, Object> result = new HashMap<>();
        if (fileMapper.insert(sysFile) > 0) {
            UserDO userDO = new UserDO();
            userDO.setUserId(userId);
            userDO.setPicId(sysFile.getId());
            if (userMapper.update(userDO) > 0) {
                result.put("url", sysFile.getUrl());
            }
        }
        return result;
    }

    @Override
    public List<UserDO> list(Map<String, Object> map) {
        return userMapper.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return userMapper.count(map);
    }

    @Transactional
    @Override
    public int save(UserDO user) {
        // 先进行用户插入，拿到用户的数据库自增Id
        int userInsert = userMapper.save(user);
        logger.info("插入新用户的自增Id为" + user.getUserId());
        for (Long roleLongId : user.getRoleIds()) {
            UserRoleDO userRoleDO = new UserRoleDO();
            userRoleDO.setRoleId(roleLongId);
            userRoleDO.setUserId(user.getUserId());
            userRoleMapper.insert(userRoleDO);
        }
        return userInsert;
    }

    @Transactional
    @Override
    public int update(UserDO user) {
        // 此处更新用户需要将用户对应的角色一并更新
        logger.info("处理用户角色，需要删除原有角色后新增角色信息");
        userRoleMapper.removeByUserId(user.getUserId());
        for (Long roleLongId : user.getRoleIds()) {
            UserRoleDO userRoleDO = new UserRoleDO();
            userRoleDO.setRoleId(roleLongId);
            userRoleDO.setUserId(user.getUserId());
            userRoleMapper.insert(userRoleDO);
        }
        // 更新用户信息
        return userMapper.update(user);
    }

    @Override
    public int remove(Long userId) {
        return userMapper.remove(userId);
    }

    @Override
    public int batchremove(Long[] userIds) {
        return userMapper.batchRemove(userIds);
    }

    @Override
    public boolean exit(Map<String, Object> params) {
        return userMapper.list(params).size() > 0 ? true : false;
    }

    /*@Override
    public Set<String> listRoles(Long userId) {
        return null;
    }*/

    @Override
    public Tree<DeptDO> getTree() {
        List<Tree<DeptDO>> trees = new ArrayList<Tree<DeptDO>>();
        // 查询部门表中所有的部门信息
        List<DeptDO> depts = deptMapper.list(new HashMap<String, Object>(16));
        // 查询部门表中所有的父节点的Id
        Long[] pDepts = deptMapper.listParentDept();
        // 查询用户表中所有的部门id
        Long[] uDepts = userMapper.listAllDept();

        Long[] allDepts = (Long[]) ArrayUtils.addAll(pDepts, uDepts);
        for (DeptDO dept : depts) {
            if (!ArrayUtils.contains(allDepts, dept.getDeptId())) {
                continue;
            }
            Tree<DeptDO> tree = new Tree<DeptDO>();
            tree.setId(dept.getDeptId().toString());
            tree.setParentId(dept.getParentId().toString());
            tree.setText(dept.getName());
            Map<String, Object> state = new HashMap<>(16);
            state.put("opened", true);
            state.put("mType", "dept");
            tree.setState(state);
            trees.add(tree);
        }
        List<UserDO> users = userMapper.list(new HashMap<String, Object>(16));
        for (UserDO user : users) {
            Tree<DeptDO> tree = new Tree<DeptDO>();
            tree.setId(user.getUserId().toString());
            tree.setParentId(user.getDeptId().toString());
            tree.setText(user.getName());
            Map<String, Object> state = new HashMap<>(16);
            state.put("opened", true);
            state.put("mType", "user");
            tree.setState(state);
            trees.add(tree);
        }
        // 默认顶级菜单为０，根据数据库实际情况调整
        Tree<DeptDO> t = BuildTreeUtil.build(trees);
        return t;
    }
}
